package mathFactsGUI;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;


import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;

import equations.MathFactsCategory;
import equations.Problem;



public class Quizzer {
	/**
	 *  JLabels for the ready set go screen
	 */
	private static JLabel ready;

	private static JLabel set;

	private static JLabel go;
	
	/**
	 *  Frame for the ready set go
	 */

	private static JFrame frame;

	/**
	 * JLabel for the actual equations
	 */
	protected JLabel equation;
	
	
	/**
	 * Stock Kumon color
	 */
	protected final static Color kumonBlue= new Color(103,238,255);
	
	
	/**
	 * Text box for entering correct answers
	 */
	private JTextField text;
	
	/**
	 * Temporary ArrayList for repeating problems with incorrect answers
	 */
	protected static ArrayList<Problem> temp;
	
	/**
	 * The arraylist which holds the original set of problems
	 */
	private ArrayList<Problem> problems;
	
	/**
	 * An arraylist that holds each of the wrong indexes entered
	 */
	private ArrayList<Integer> wrongIndexes = new ArrayList<Integer>();
	
	/**
	 * An ArrayList that holds the original list of wrong answers
	 */
	private ArrayList<String> wrongAnswers = new ArrayList<String>();
	
	/**
	 * Stores the indexes of answers that were incorrect for repeates
	 */
	private static ArrayList<Integer> wrongIndexes2 = new ArrayList<Integer>();
	
	/**
	 * Stores the second set of wrong answers
	 */
	private ArrayList<String> wrongAnswers2= new ArrayList<String>();
	
	/**
	 * The answer to a problem entered by the user
	 */
	protected String answer;
	
	/**
	 * The left JPanel in which the equation is displayed
	 */
	protected JPanel left;
	
	/**
	 * The current problem that the user is on
	 */
	private int current =0;
	
	/**
	 * The total number wrong after corrections
	 */
	protected long firstCorrect=0;
	
	/**
	 * The number of correct answers after corrections were made
	 */
	protected long secondCorrect=0;
	
	/**
	 * The actual quiz graphic user interface
	 */
	protected static JFrame quizGUI;
	
	/**
	 * The time it took the student to complete the first set of the work
	 */
	protected static long firstCompletionTime=0;
	
	/**
	 * The time it took to make corrections
	 */
	protected long correctionCompletionTime = 0;
	
	/**
	 * The time when the quiz begins in nano seconds
	 */
	private static long startTime=0;
	
	/**
	 * The time when the quiz ends in nanoseconds
	 */
	private long endTime =0;
	
	/**
	 * The JFrame that displays congrats for perfect score
	 */
	private static JFrame congratsScreen;
	
	/**
	 * Time to complete the set of corrections
	 */
	private static long secondCompletionTime;
	
	/**
	 * The second message to be displayed in the corrections screen
	 */
	private static JLabel messageDisplayed2;
	
	protected static PrintWriter output;
	
	
	/**
	 * Constructor for the display screen that will quiz the student
	 * @param mfc
	 */
	public Quizzer(MathFactsCategory mfc) {
		
		quizGUI = new JFrame();
		
		//populate all the problems
		problems = mfc.getProblem1();
		problems.addAll(mfc.getProblem2());
		problems.addAll(mfc.getProblem3());
		problems.addAll(mfc.getProblem4());
		problems.addAll(mfc.getProblem5());
		problems.addAll(mfc.getProblem6());
		problems.addAll(mfc.getProblem7());
		problems.addAll(mfc.getProblem8());
		problems.addAll(mfc.getProblem9());
		
		Quizzer.setUp();
		
		left = new JPanel();
		left.setLayout(new BorderLayout());
		equation = new JLabel(problems.get(0).getEquation());
		Font defaultFont = new Font("Comic Sans MS", Font.BOLD, 150);
		equation.setFont(defaultFont);
		left.setBackground(kumonBlue);
		left.add(equation, BorderLayout.CENTER);
		
		JPanel right = new JPanel();
		right.setBackground(kumonBlue);
		right.setLayout(new BorderLayout());
		text = new JTextField(3);
		text.setFont(defaultFont);
		Insets inset = new Insets(30, 30, 30, 30);
		text.setMargin(inset);
		text.addActionListener(new ActionListener(){

			

			@Override
			public void actionPerformed(ActionEvent arg0) {
			 answer = text.getText();
			 text.setText("");
			 ArrayList<Problem> problemRef = problems;
			 //if all the problems haven't been run through yet
			 if(current<problems.size()){
				
				 if(problemRef.get(current).getSolution().equals(answer)){
					 current++;
					 if(current!=problems.size()){
						 equation.setText(problems.get(current).getEquation());
						 equation.revalidate();
					 }
				 }
				 else{
					 wrongIndexes.add(current);
				 	 wrongAnswers.add(answer);
				 	 current++;
				 	 if(current!=problems.size()){
						 equation.setText(problems.get(current).getEquation());
						 equation.revalidate();
					 }

				 }
				 //all problems have been covered once
				 if (current==problems.size()){
					 quizGUI.dispose();
					 current=0;
					 endTime=System.nanoTime();
					 
					 firstCorrect = problems.size()-wrongIndexes.size();
					 firstCompletionTime = (endTime-startTime)/1000000000;
					 
					 
					 if(wrongIndexes.size()==0){
						 
						 createCongratsScreen();
						 output.println("Completion Time: "+getFirstCompletionTime()/60 + " min " + getFirstCompletionTime()%60+ " sec");
						 output.println("Number Correct: "+ (getProblems().size()-getWrongAnswers().size())+" out of "+getProblems().size());
						 output.println("End session");
						 output.println(" ");
						 output.close();
						 
					 }else{
						 
						
						 temp = new ArrayList<Problem>();
						 
						 for(int i : wrongIndexes){
							 temp.add(problems.get(i));
						 }
						 
						 
						 quizGUI = new JFrame();
						 Quizzer.setUp();
						 	
						 left = new JPanel();
						 left.setLayout(new BorderLayout());
						 equation = new JLabel(temp.get(0).getEquation());
						 Font defaultFont = new Font("Comic Sans MS", Font.BOLD, 150);
						 equation.setFont(defaultFont);
						 left.setBackground(kumonBlue);
						 left.add(equation, BorderLayout.CENTER);
							
						 JPanel right = new JPanel();
						 right.setBackground(kumonBlue);
						 right.setLayout(new BorderLayout());
						 text = new JTextField(3);
						 text.setFont(defaultFont);
						 Insets inset = new Insets(30, 30, 30, 30);
						 text.setMargin(inset);
						 text.addActionListener(new ActionListener(){
							 

							@Override
							 public void actionPerformed(ActionEvent arg0) {
								 answer = text.getText();
								 text.setText("");
								 
								 if(current<temp.size()){
										
									 if(temp.get(current).getSolution().equals(answer)){
										 current++;
										 if(current!=temp.size()){
											 equation.setText(temp.get(current).getEquation());
											 equation.revalidate();
										 }
									 }//end if
									 else{
										 wrongIndexes2.add(current);
									 	 wrongAnswers2.add(answer);
									 	 current++;
									 	 if(current!=temp.size()){
											 equation.setText(temp.get(current).getEquation());
											 equation.revalidate();
										 }

									 }//end else
									 
									 if (current==temp.size()){
										 quizGUI.dispose();
										 current=0;
										 endTime=System.nanoTime();
										 
										 secondCompletionTime = (endTime-startTime)/1000000000;
										 correctionsResultsScreen();
											output.println("Completion Time: "+getFirstCompletionTime()/60 + " min " + getFirstCompletionTime()%60+ " sec");
											output.println("Number Correct: "+ (getProblems().size()-getWrongAnswers().size())+" out of "+getProblems().size());
											output.println("Corrections Completion Time: "+ secondCompletionTime/60 +" min "+secondCompletionTime%60+ " sec");
											output.println("Number Correct: " + (getWrongEquations().size()-getWrongIndexes2().size() +" out of "+ getWrongEquations().size()));
											output.println("End session");
											output.println(" ");
											output.close();
									}

									 }//end if
								 }//end if
							 //end actionPerformed
					 
						 });
						 
						 quizGUI.add(left);
							right.add(new JLabel(" \n"), BorderLayout.NORTH);
							right.add(new JLabel(" \n"), BorderLayout.SOUTH);
							right.add(new JLabel("                "), BorderLayout.EAST);
							right.add(text,BorderLayout.CENTER);
							quizGUI.add(right);
							quizGUI.setVisible(true);
							readySetGo(""+(problems.size()-wrongAnswers.size())+" correct out of " + problems.size(),"Completion Time: "+firstCompletionTime/60+" mins "+firstCompletionTime%60+" secs");
							
					 }//end else
				 }//end if current==problems.size()

			 }//Now that the problems have been run through once, we retest the child as long as boolean secondRun is true
		
				}//end action performed


		});//end action listener
		
		quizGUI.add(left);
		right.add(new JLabel(" \n"), BorderLayout.NORTH);
		right.add(new JLabel(" \n"), BorderLayout.SOUTH);
		right.add(new JLabel("                "), BorderLayout.EAST);
		right.add(text,BorderLayout.CENTER);
		quizGUI.add(right);
		
		
		Quizzer.readySetGo(mfc.toString());
		
		Timer startGUI = new Timer();
		TimerTask showGUI = new TimerTask(){
			public void run(){
				quizGUI.setVisible(true);
			}
		};
		startGUI.schedule(showGUI, 4000);
		
		
	}//End constructor
	
	/**
	 * Gets the ArrayList of Problems
	 * @return problems
	 */
	public ArrayList<Problem> getProblems(){
		return problems;
		
	}
	

	/**
	 * Helper method Sets up the JFrme
	 */
	private static void setUp() {
		quizGUI.setSize(new Dimension(800, 300));
		quizGUI.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		
		// centers the JFrame on screen
		Dimension screenSizes = Toolkit.getDefaultToolkit().getScreenSize();
		int heights = screenSizes.height;
		int widths = screenSizes.width;
		quizGUI.setLayout(new GridLayout(1,0));
		quizGUI.setSize((int)(widths*.9), heights / 2);
		quizGUI.setLocationRelativeTo(null);

	}// Sets up the JFrame
	
	/**
	 * Ready set go JFrame
	 * @param message
	 */
	private static void readySetGo(String message){
		frame = new JFrame();
		JPanel rsg = new JPanel();
		rsg.setBackground(kumonBlue);
		Font readyFont = new Font("Comic Sans MS", Font.BOLD, 50);
		
		JLabel messageDisplayed = new JLabel(message, SwingConstants.CENTER);
		if(message.charAt(0)!='*'){
			messageDisplayed.setFont(readyFont);
		}else{
			Font alternate = new Font("Comic Sans MS", Font.BOLD, 25);
			messageDisplayed.setFont(alternate);
		}
		ready = new JLabel("", SwingConstants.CENTER);
		ready.setFont(readyFont);
		ready.setForeground(Color.red);
		
		set = new JLabel("", SwingConstants.CENTER);
		set.setFont(readyFont);
		set.setForeground(Color.yellow);
		
		go = new JLabel("", SwingConstants.CENTER);
		go.setFont(readyFont);
		go.setForeground(Color.green);
		
		
		GridLayout grid = new GridLayout(0,1);
		
		rsg.setLayout(grid);
		rsg.add(messageDisplayed);
		rsg.add(ready);
		rsg.add(set);
		rsg.add(go);
		frame.setSize(700,500);
		
		frame.add(rsg);
		frame.setLocationRelativeTo(null);
		frame.setVisible(true);
		
		Timer timing = new Timer();
		
		TimerTask readyTask = new TimerTask(){
			public void run(){
				ready.setText("Ready!");
				ready.revalidate();
			}
		};
		TimerTask setTask = new TimerTask(){
			public void run(){
				set.setText("Get Set!");
				set.revalidate();
			}
		};
		TimerTask goTask = new TimerTask(){
			public void run(){
				go.setText("Go!");
				go.revalidate();
				
			}
		};
		
		TimerTask end = new TimerTask(){
			public void run(){
				frame.dispose();
				startTime=System.nanoTime();
			}
		};
		
		
		
		timing.schedule(readyTask, 1000);
		timing.schedule(setTask,2000);
		timing.schedule(goTask,3000);
		timing.schedule(end, 4000);
		
		
	}
	
	private void readySetGo(String message, String message2) {
		frame = new JFrame();
		JPanel rsg = new JPanel();
		rsg.setBackground(kumonBlue);
		Font readyFont = new Font("Comic Sans MS", Font.BOLD, 50);
		
		JLabel messageDisplayed = new JLabel(message, SwingConstants.CENTER);
		messageDisplayed2 = new JLabel("", SwingConstants.CENTER);
		Font alternate = new Font("Comic Sans MS", Font.BOLD, 25);
		messageDisplayed.setFont(alternate);
		messageDisplayed2.setFont(alternate);
		
		
		
		ready = new JLabel("", SwingConstants.CENTER);
		ready.setFont(readyFont);
		ready.setForeground(Color.red);
		
		set = new JLabel("", SwingConstants.CENTER);
		set.setFont(readyFont);
		set.setForeground(Color.yellow);
		
		go = new JLabel("", SwingConstants.CENTER);
		go.setFont(readyFont);
		go.setForeground(Color.green);
		
		
		GridLayout grid = new GridLayout(0,1);
		
		rsg.setLayout(grid);
		rsg.add(messageDisplayed);
		rsg.add(messageDisplayed2);
		rsg.add(ready);
		rsg.add(set);
		rsg.add(go);
		frame.setSize(500,500);
		
		frame.add(rsg);
		frame.setLocationRelativeTo(null);
		frame.setVisible(true);
		
		Timer timing = new Timer();
		final String temp = message2;
		
		TimerTask timeTask = new TimerTask(){
			public void run(){
				messageDisplayed2.setText(temp);
			}
		};
		TimerTask readyTask = new TimerTask(){
			public void run(){
				ready.setText("Ready!");
				ready.revalidate();
			}
		};
		TimerTask setTask = new TimerTask(){
			public void run(){
				set.setText("Get Set!");
				set.revalidate();
			}
		};
		TimerTask goTask = new TimerTask(){
			public void run(){
				go.setText("Go!");
				go.revalidate();
				
			}
		};
		
		TimerTask end = new TimerTask(){
			public void run(){
				frame.dispose();
				startTime=System.nanoTime();
			}
		};
		
		
		
		timing.schedule(timeTask, 1000);
		timing.schedule(readyTask,2000);
		timing.schedule(setTask,3000);
		timing.schedule(goTask, 4000);
		timing.schedule(end, 4500);
		
	}
	
	/**
	 * Creates a congratulations screen if the student gets a perfect score
	 */
	private static void createCongratsScreen(){
		
		 //creates a pop up that congratulates the student on a perfect score
		 Font congratsFont = new Font("Comic Sans MS", Font.BOLD, 40);
		 Font timeFont = new Font("Comic Sans MS", Font.BOLD, 25);
		 String congrats = "Great Work!!! You got a perfect score!";
		 String completionTime= "Completion time is: "+firstCompletionTime/60 +" minutes "+firstCompletionTime%60+ " seconds";
		 ImageIcon congratsIcon = new ImageIcon("C://Kumon//graphics//Congrats.jpg");
		 
		 JLabel congratsIconDisplayed = new JLabel(congratsIcon);
		 
		 JLabel congratsLabel = new JLabel(congrats);
		 congratsLabel.setFont(congratsFont);
		 
		 JLabel timeLabel = new JLabel(completionTime);
		 timeLabel.setFont(timeFont);
		 
		 JPanel top = new JPanel();
		 top.setBackground(kumonBlue);
		 JPanel bottem = new JPanel();
		 bottem.setBackground(kumonBlue);
		 JPanel center = new JPanel();
		 center.setBackground(kumonBlue);
		 center.add(congratsIconDisplayed);
		 
		 top.add(congratsLabel);
		 bottem.add(timeLabel);
		 
		 congratsScreen = new JFrame();
		 congratsScreen.setLayout(new BorderLayout());
		 
		 congratsScreen.add(top,BorderLayout.NORTH);
		 congratsScreen.add(bottem,BorderLayout.SOUTH);
		 congratsScreen.add(center, BorderLayout.CENTER);
		 congratsScreen.pack();
		 congratsScreen.setLocationRelativeTo(null);
		 congratsScreen.setVisible(true);
		 
		 Timer congratsTiming = new Timer();
		 
		 TimerTask exitCongrats = new TimerTask(){
			 public void run(){
				 congratsScreen.dispose();
			 }
		 };
		 
		 congratsTiming.schedule(exitCongrats, 3000);
		 
		
	}
	
	
	
	/**
	 * Pop up that shows the final results after corrections have been made
	 */
	private static void correctionsResultsScreen(){
		//creates a pop up that shows the student how many wrong answers they had
		 Font correctionsFont = new Font("Comic Sans MS", Font.BOLD, 40);
		 Font timeFont = new Font("Comic Sans MS", Font.BOLD, 25);
		 
		 String congrats;
		 ImageIcon congratsIcon = new ImageIcon("C://Kumon//graphics//Congrats.jpg");
		 JLabel congratsIconDisplayed;
		 
		 if(wrongIndexes2.size()==0){
			 congrats = "Good Job! You got "+(temp.size()-wrongIndexes2.size())+" corrections out of "+temp.size() +" problems correct!";
			 congratsIconDisplayed = new JLabel(congratsIcon);
		 }else{
			 congrats = "Nice try, you got "+(temp.size()-wrongIndexes2.size())+" out of "+temp.size()+" correct!";
			 congratsIconDisplayed = new JLabel();
		 }
		 
		 String completionTime= "Completion time is: "+(secondCompletionTime/60) +" minutes "+(secondCompletionTime%60)+ " seconds";
		 
		 
		 
		 
		 JLabel congratsLabel = new JLabel(congrats);
		 congratsLabel.setFont(correctionsFont);
		 
		 JLabel timeLabel = new JLabel(completionTime);
		 timeLabel.setFont(timeFont);
		 
		 JPanel top = new JPanel();
		 top.setBackground(kumonBlue);
		 JPanel bottem = new JPanel();
		 bottem.setBackground(kumonBlue);
		 JPanel center = new JPanel();
		 center.setBackground(kumonBlue);
		 center.add(congratsIconDisplayed);
		 
		 top.add(congratsLabel);
		 bottem.add(timeLabel);
		 
		 congratsScreen = new JFrame();
		 congratsScreen.setLayout(new BorderLayout());
		 
		 congratsScreen.add(top,BorderLayout.NORTH);
		 congratsScreen.add(bottem,BorderLayout.SOUTH);
		 congratsScreen.add(center, BorderLayout.CENTER);
		 congratsScreen.pack();
		 congratsScreen.setLocationRelativeTo(null);
		 congratsScreen.setVisible(true);
		 
		 Timer congratsTiming = new Timer();
		 
		 TimerTask exitCongrats = new TimerTask(){
			 public void run(){
				 congratsScreen.dispose();
			 }
		 };
		 
		 congratsTiming.schedule(exitCongrats, 3000);
		 
	}
	
	/**
	 * Getter method taht returns wrongAnswers
	 * @return
	 */
	public ArrayList<String> getWrongAnswers(){
		return wrongAnswers;
	}
	
	/**
	 * Getter method that returns wrongIndexes
	 */
	public ArrayList<Integer> getWrongIndexes(){
		return wrongIndexes;
	}
	
	/**
	 * Returns the array List of equations to be corrected
	 */
	public ArrayList<Problem> getWrongEquations(){
		return temp;
	}
	
	/**
	 * Returns the original set of problems
	 * @return
	 */
	public ArrayList<Problem> getOriginalProblemSet(){
		return problems;
	}
	
	/**
	 * Returns the completion time for the first set of problems
	 * @return
	 */
	public long getFirstCompletionTime(){
		return firstCompletionTime;
	}
	
	/**
	 * Returns the completion time for the corrections
	 * @return
	 */
	public long getCorrectionCompletionTime(){
		return correctionCompletionTime;
	}
	
	public ArrayList<Integer> getWrongIndexes2(){
		return wrongIndexes2;
	}
}